package hk.edu.polyu.comp.motioncapture.application;

import hk.edu.polyu.comp.motioncapture.*;
import hk.edu.polyu.comp.motioncapture.analysis.command.Command;
import hk.edu.polyu.comp.motioncapture.point.*;
import hk.edu.polyu.comp.motioncapture.userApplication.Sender;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
import java.awt.Color;
import java.awt.ComponentOrientation;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.UIManager;

public class TestGUI {

	private JLabel soundLabel;
	private JLabel mouseStatusLabel;
	private JLabel kbCommandLabel;
	private JLabel commandLabel;
	private JTextArea textArea;
	private JFrame frame;
	private JLabel fpsLabel;
	private JLabel avgfpsLabel;
	private JLabel areaLabel;
	private JTextField time;
	private JButton confirmButton;
	private JLabel statusLabel;
	private JLabel ptLabel;

	int timeBtwAnalysisPoint;

	/**
	 * Launch the application
	 * 
	 * @param args
	 */
	public static void main(String args[]) {

		// System variable
		boolean isAddStartNotice = false;
		boolean isMouseLeftDown = false;
		boolean isMouserightDown = false;

		TestGUI window = new TestGUI();
		window.frame.setVisible(true);

		Screen screen = new Screen();
		Command cmd = new Command(screen);

		try {
			Camera camera = new Camera(true, false, screen);
			camera.run();

			window.textArea.append("Waiting OptiTrack.. \n");
			window.textArea.append("Waiting Client Application.. \n");

			Sender sender = new Sender();
			sender.startConnection();
			window.textArea.append("Client Application start.. \n");

			while (camera.isRunning()) {

				// Sound Handling
				// if (camera.hasSoundCommand()) {
				// window.soundLabel.setText(camera.getSoundCommand());
				// sender.sendCommand(camera.getSoundCommand());
				// System.out.println("Send sound: "
				// + camera.getSoundCommand());
				// }

				if (camera.getRunTime() % 10 == 0) {
					// Get the last OptiPoint without repeat
					Frame pointSet = camera.returnLastPointSet(false);

					if (pointSet != null) {
						// Add a Start Notice
						if (!isAddStartNotice) {
							window.textArea.append("Camera start.. \n");
							isAddStartNotice = true;
						}

						// Get the screen
						if (camera.getRunTime() > 2500 && !screen.isExist()) {
							if (screen.getScreen(camera)) {
								window.textArea.append("Screen captured.. \n");

								sender.sendCommand("screen");
								window.setStatusLabel("(Captured)");
								window.setPtLabell(screen.toString());

								// System.out.println(screen.toString());
							}
						}

						// Update the FPS per second
						if ((camera.getRunTime() % 1000) == 0) {
							window.fpsLabel.setText("FPS: " + camera.getFPS());
							window.avgfpsLabel.setText("Avg FPS: "
									+ camera.getAverageFPS());
						}

						// Checking command
						if (camera.getRunTime() > 3000 && screen.isExist()) {
							cmd.setAnalysisVector(camera
									.returnTimePointSets(0.5));

							boolean mouseCommandExist = true;
							boolean kbCommandExist = true;

							double rotation = cmd.getRotation(2, true);

							// Mouse Left Click
							if (cmd.isMouseLeftClick(10) && !isMouseLeftDown) {
								window.mouseStatusLabel
										.setText("mouse_leftClickDown");
								sender.sendCommand("mouse_leftClickDownEND");
								isMouseLeftDown = true;
							} else if (!cmd.isMouseLeftClick(10)
									&& isMouseLeftDown) {
								window.mouseStatusLabel
										.setText("mouse_leftClickUp");
								sender.sendCommand("mouse_leftClickUpEND");
								isMouseLeftDown = false;
							}

							// Mouse Right Click
							if (cmd.isMouseRightClick(10) && !isMouserightDown) {
								window.mouseStatusLabel
										.setText("mouse_rightClickDown");
								sender.sendCommand("mouse_rightClickDownEND");
								isMouserightDown = true;
							} else if (!cmd.isMouseRightClick(10)
									&& isMouserightDown) {
								window.mouseStatusLabel
										.setText("mouse_rightClickUpEND");
								sender.sendCommand("mouse_rightClickUpEND");
								isMouserightDown = false;
							}

							// Mouse Event
							if (cmd.isMouseMove(40, 4, true)) {

								Point op = screen.transformation(cmd
										.getReturnPoint());
								window.commandLabel.setText("mouse_moveEND");
								sender.sendCommand("mouse_move "
										+ (int) op.getX() + " " + op.getY()
										+ "END");

							} else if (cmd.isScrollDown(2, true)) {
								window.commandLabel
										.setText("mouse_scroll_downEND");
								sender.sendCommand("mouse_scroll_downEND");

							} else if (cmd.isScrollUp(2, true)) {
								window.commandLabel
										.setText("mouse_scroll_upEND");
								sender.sendCommand("mouse_scroll_upEND");
							} else if (rotation > 0) {
								window.commandLabel
										.setText("mouse_rotate_leftEND");
								sender.sendCommand("mouse_rotate_leftEND");
							} else if (rotation < 0) {
								window.commandLabel
										.setText("mouse_rotate_rightEND");
								sender.sendCommand("mouse_rotate_rightEND");
							} else {
								mouseCommandExist = false;
								window.commandLabel.setText("No command");
							}

							// Keyboard command
							// if (cmd.isCtrlDown()) {
							// window.kbCommandLabel.setText("Press Control
							// Key");
							// sender.sendCommand("kb_controlEND");
							// } else {
							// kbCommandExist = false;
							// window.kbCommandLabel.setText("No command");
							// }

							// Keyboard command
							if (cmd.isUp(20)) {
								window.kbCommandLabel.setText("kb_upEND");
								sender.sendCommand("kb_upEND");
							} else if (cmd.isDown(20)) {
								window.kbCommandLabel.setText("kb_downEND");
								sender.sendCommand("kb_downEND");
							} else {
								window.kbCommandLabel.setText("");
								kbCommandExist = false;
							}

							if (!kbCommandExist && !mouseCommandExist)
								sender.sendCommand("No Command");
						}
					}
				}
			}
			sender.closeSender();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Create the application
	 */
	public TestGUI() {

		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
		}

		initialize();

		timeBtwAnalysisPoint = Integer.parseInt(time.getText());
	}

	/**
	 * Initialize the contents of the frame
	 */
	private void initialize() {
		frame = new JFrame();
		frame.setTitle("Motion Capture Analysis Server");
		frame.getContentPane().setLayout(null);
		frame.setBounds(100, 100, 627, 375);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		final JLabel timeBetweenEachLabel = new JLabel();
		timeBetweenEachLabel.setText("Time between each analysis point: (ms)");
		timeBetweenEachLabel.setBounds(10, 138, 189, 14);
		frame.getContentPane().add(timeBetweenEachLabel);

		textArea = new JTextArea();
		textArea.setFont(new Font("", Font.PLAIN, 10));
		textArea.setBorder(new LineBorder(Color.black, 1, false));
		textArea.setBounds(385, 10, 224, 321);
		frame.getContentPane().add(textArea);

		fpsLabel = new JLabel();
		fpsLabel.setText("FPS:");
		fpsLabel.setBounds(10, 10, 102, 14);
		frame.getContentPane().add(fpsLabel);

		avgfpsLabel = new JLabel();
		avgfpsLabel.setText("AvgFPS:");
		avgfpsLabel.setBounds(118, 11, 102, 14);
		frame.getContentPane().add(avgfpsLabel);

		areaLabel = new JLabel();
		areaLabel.setText("Area");
		areaLabel.setBounds(226, 10, 54, 14);
		frame.getContentPane().add(areaLabel);

		commandLabel = new JLabel();
		commandLabel.setText("Command");
		commandLabel.setBounds(118, 35, 130, 14);
		frame.getContentPane().add(commandLabel);

		kbCommandLabel = new JLabel();
		kbCommandLabel.setText("Command");
		kbCommandLabel.setBounds(118, 52, 130, 14);
		frame.getContentPane().add(kbCommandLabel);

		final JLabel mouseCommandLabel = new JLabel();
		mouseCommandLabel.setText("Mouse Command:");
		mouseCommandLabel.setBounds(10, 34, 124, 14);
		frame.getContentPane().add(mouseCommandLabel);

		final JLabel mouseCommandLabel_1 = new JLabel();
		mouseCommandLabel_1.setText("Keyboard Command:");
		mouseCommandLabel_1.setBounds(10, 52, 124, 14);
		frame.getContentPane().add(mouseCommandLabel_1);

		final JPanel panel = new JPanel();
		panel.setLayout(null);
		panel.setBorder(new TitledBorder(null, "",
				TitledBorder.DEFAULT_JUSTIFICATION,
				TitledBorder.DEFAULT_POSITION, null, null));
		panel.setBounds(10, 219, 369, 112);
		frame.getContentPane().add(panel);

		final JLabel screenDetailLabel = new JLabel();
		screenDetailLabel.setBounds(10, 10, 108, 14);
		panel.add(screenDetailLabel);
		screenDetailLabel.setText("Screen detail:");

		statusLabel = new JLabel();
		statusLabel.setText("(Not Capture)");
		statusLabel.setBounds(90, 10, 269, 14);
		panel.add(statusLabel);

		ptLabel = new JLabel();
		ptLabel.setBounds(10, 30, 349, 72);
		panel.add(ptLabel);

		final JSeparator separator = new JSeparator();
		separator.setBounds(10, 124, 369, 8);
		frame.getContentPane().add(separator);

		time = new JTextField();
		time.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
		time.setText("20");
		time.setBounds(201, 135, 79, 20);
		frame.getContentPane().add(time);

		confirmButton = new JButton();
		confirmButton.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent arg0) {
				timeBtwAnalysisPoint = Integer.parseInt(time.getText());
			}
		});
		confirmButton.setText("Confirm");
		confirmButton.setBounds(286, 134, 93, 23);
		frame.getContentPane().add(confirmButton);

		final JLabel mouseStatusLabel_1 = new JLabel();
		mouseStatusLabel_1.setText("Mouse Status:");
		mouseStatusLabel_1.setBounds(10, 72, 124, 14);
		frame.getContentPane().add(mouseStatusLabel_1);

		mouseStatusLabel = new JLabel();
		mouseStatusLabel.setText("Command");
		mouseStatusLabel.setBounds(118, 72, 130, 14);
		frame.getContentPane().add(mouseStatusLabel);

		soundLabel = new JLabel();
		soundLabel.setText("Command");
		soundLabel.setBounds(118, 92, 130, 14);
		frame.getContentPane().add(soundLabel);

		final JLabel mouseStatusLabel_1_1 = new JLabel();
		mouseStatusLabel_1_1.setText("Mouse Status:");
		mouseStatusLabel_1_1.setBounds(10, 92, 124, 14);
		frame.getContentPane().add(mouseStatusLabel_1_1);
	}

	public void setStatusLabel(String str) {
		statusLabel.setText(str);
	}

	public void setPtLabell(String str) {
		ptLabel.setText(str);
	}

}
